﻿using MQTTnet.Client.Options;
using MQTTnet.Client;
using System;
using MQTTnet.Client.Disconnecting;
using MQTTnet;
using Newtonsoft.Json;
using System.Threading.Tasks;
using XiAnAirport.Models;
using System.Text;
using System.Collections.Generic;

namespace XiAnAirport.BUS.Mqtt
{
    public class FXMqttShareClient
    {
        IMqttClient _mqttShareClient;
        MqttClientOptions _options;
        string version = string.Empty;
        public static string Master;
        public static bool SlaveConnect = false;
        public static List<string> control = new List<string>();

        public FXMqttShareClient()
        {
            try
            {
                version = AppSettingsHelper.Configuration["MqttClient:Version"];
                Master = AppSettingsHelper.Configuration["MqttServer:Master"];
                Init();
            }
            catch (Exception ex)
            {
                LogHelper.MqttLog("Mqtt:" + ex.ToString());
            }
        }

        public IMqttClient MqttShareClient { get { return _mqttShareClient; } }

        private void Init()
        {
            try
            {
                _mqttShareClient = new MqttFactory().CreateMqttClient();

                _mqttShareClient.UseApplicationMessageReceivedHandler(async c =>
                {
                    try
                    {
                        string topic = c.ApplicationMessage.Topic;
                        string payload = Encoding.UTF8.GetString(c.ApplicationMessage.Payload ?? new byte[] { });
                        if (topic == version + "/KoneDeviceStateSync")
                        {
                            KoneDeviceStateSync koneDeviceStateSync = JsonConvert.DeserializeObject<KoneDeviceStateSync>(payload);
                            if (koneDeviceStateSync != null)
                            {
                                if (koneDeviceStateSync.Elevator_control_status == 99)
                                {
                                    LogHelper.MqttLog(payload);
                                }
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                elevatorStateBUS.MqttKoneDeviceSync(koneDeviceStateSync);
                            }
                        }
                        else if (topic == version + "/KoneDeviceFault")
                        {
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            KoneFaultReport faultRecordReport = JsonConvert.DeserializeObject<KoneFaultReport>(payload);
                            if (faultRecordReport != null)
                            {
                                if (Master == "1" || !SlaveConnect)
                                {
                                    mqttDataBUS.KoneFaultRecord(faultRecordReport);
                                }
                                else
                                {
                                    Wait(1000);
                                    mqttDataBUS.SlaveKoneFaultRecord(faultRecordReport);
                                }
                            }
                        }
                        else if (topic == version + "/KoneDeviceTemperature")
                        {
                            KoneDeviceTemperature koneDeviceTemperature = JsonConvert.DeserializeObject<KoneDeviceTemperature>(payload);
                            if (koneDeviceTemperature != null)
                            {
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                elevatorStateBUS.KoneDeviceTemperature(koneDeviceTemperature);
                            }
                        }
                        else if (topic == version + "/PushKoneDeviceData")
                        {
                            LogHelper.Log("接收到同步的数据：" + payload);
                            List<ShareData> shareData = JsonConvert.DeserializeObject<List<ShareData>>(payload);
                            if (shareData != null)
                            {
                                ElevatorStateBUS elevatorStateBUS = new ElevatorStateBUS();
                                foreach (var item in shareData)
                                {
                                    if (item.type == "StateSync")
                                    {
                                        List<LiftStateALL> liftStates = JsonConvert.DeserializeObject<List<LiftStateALL>>(item.message.ToString());
                                        elevatorStateBUS.UpdateElevatorState(liftStates);
                                    }
                                    else if (item.type == "RuntimeSync")
                                    {
                                        List<ElevatorStateRunTime> timelist = JsonConvert.DeserializeObject<List<ElevatorStateRunTime>>(item.message.ToString());
                                        elevatorStateBUS.UpdateRunTimeList(timelist);
                                    }
                                    else if (item.type == "RunSync")
                                    {
                                        List<ElevatorStateRun> runlist = JsonConvert.DeserializeObject<List<ElevatorStateRun>>(item.message.ToString());
                                        elevatorStateBUS.UpdateRunList(runlist);
                                    }
                                }
                            }
                        }
                        else if (topic == version + "/KoneDeviceControl")
                        {
                            RemoteLockLadderInfo remoteLockLadderInfo = JsonConvert.DeserializeObject<RemoteLockLadderInfo>(payload);
                            if (remoteLockLadderInfo != null)
                            {
                                int index = control.FindIndex(x => x == remoteLockLadderInfo.opcNO);
                                if (index > -1)
                                {
                                    control.Remove(control[index]);
                                }
                                else
                                {
                                    MqttServerBUS BUS = new MqttServerBUS();
                                    await BUS.PublicAsyncMessage(version + "/KoneDeviceControl", payload, 0);
                                    // control.Add(remoteLockLadderInfo.opcNO);
                                }
                            }

                        }
                    }
                    catch (Exception e)
                    {

                    }
                });
                _mqttShareClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(e =>
                {
                    StartConnect();
                });
                _options = new MqttClientOptions()
                {
                    //ClientId = CommVars.Configuration.GetSection("MqttServer").GetSection("ClientId").Value
                    ClientId = Guid.NewGuid().ToString() + "DataShare"
                };
                _options.ChannelOptions = new MqttClientTcpOptions()
                {
                    Server = AppSettingsHelper.Configuration["MqttClient:Server"],
                    Port = int.Parse(AppSettingsHelper.Configuration["MqttClient:Port"]),
                };
                string strName = AppSettingsHelper.Configuration["MqttClient:Username"];
                if (!string.IsNullOrEmpty(strName))
                {
                    _options.Credentials = new MqttClientCredentials()
                    {
                        Username = strName,
                        Password = System.Text.Encoding.Default.GetBytes(AppSettingsHelper.Configuration["MqttClient:Password"])
                    };
                }
                _options.CleanSession = true;
                _options.KeepAlivePeriod = TimeSpan.FromSeconds(5);
                StartConnect();
            }
            catch (Exception ex)
            {

            }

        }
        public async void StartConnect()
        {

            //LogHelper.Log("启动");
            Task t = Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    try
                    {
                        if (!_mqttShareClient.IsConnected)
                        {
                            await _mqttShareClient.ConnectAsync(_options);
                            await _mqttShareClient.SubscribeAsync(version + "/KoneDeviceFault", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);
                            await _mqttShareClient.SubscribeAsync(version + "/KoneDeviceStateSync", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            await _mqttShareClient.SubscribeAsync(version + "/KoneDeviceTemperature", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            await _mqttShareClient.SubscribeAsync(version + "/KoneDeviceControl", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            //await _mqttShareClient.SubscribeAsync(version + "/PushKoneDeviceData", MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
                            //同步数据
                            SyncData();
                            //故障记录去掉重复项
                            MqttDataBUS mqttDataBUS = new MqttDataBUS();
                            mqttDataBUS.DistinctData();
                        }
                        else
                        {
                            if (!SlaveConnect)
                            {
                                SlaveConnect = true;
                            }
                            break;
                        }
                    }
                    catch (Exception ex)
                    {

                    }

                    Task.Delay(10000).Wait();
                }
            });

        }

        public async void SyncData()
        {
            MqttServerBUS BUS = new MqttServerBUS();
            List<ShareData> list = new List<ShareData>();
            //状态同步
            if (ElevatorStateBUS.state_list != null && ElevatorStateBUS.state_list.Count > 0)
            {
                ShareData shareData = new ShareData();
                shareData.type = "StateSync";
                shareData.message = ElevatorStateBUS.state_list;
                list.Add(shareData);
            }
            //运行时间
            if (ElevatorStateBUS.runtime_list != null && ElevatorStateBUS.runtime_list.Count > 0)
            {
                ShareData shareData = new ShareData();
                shareData.type = "RuntimeSync";
                shareData.message = ElevatorStateBUS.runtime_list;
                list.Add(shareData);
            }
            //运行次数
            if (ElevatorStateBUS.run_list != null && ElevatorStateBUS.run_list.Count > 0)
            {
                ShareData shareData = new ShareData();
                shareData.type = "RunSync";
                shareData.message = ElevatorStateBUS.run_list;
                list.Add(shareData);
            }

            if (list.Count > 0)
            {
                LogHelper.Log("发布同步数据" + JsonConvert.SerializeObject(list));
                await BUS.SendShareMessage(version + "/PushKoneDeviceData", JsonConvert.SerializeObject(list), 0);
            }
        }

        public bool Wait(int milliseconds)
        {
            try
            {
                DateTime startTime = DateTime.Now;
                while (true)
                {
                    TimeSpan secondSpan = new TimeSpan(DateTime.Now.Ticks - startTime.Ticks);
                    if (secondSpan.TotalMilliseconds > milliseconds)
                    {
                        break;
                    }
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
    }
}
